home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
pcr
/
pcr4_4.lha
/
DIST
/
gc
/
GChdr_alloc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-11
|
5KB
|
169 lines
/* begincopyright
Copyright (c) 1988,1990 Xerox Corporation. All rights reserved.
Use and copying of this software and preparation of derivative works based
upon this software are permitted. Any distribution of this software or
derivative works must comply with all applicable United States export
control laws. This software is made available AS IS, and Xerox Corporation
makes no warranty about the software, its performance or its conformity to
any specification. Any person obtaining a copy of this software is requested
to send their name and post office or electronic mail address to:
PCR Coordinator
Xerox PARC
3333 Coyote Hill Rd.
Palo Alto, CA 94304
Parts of this software were derived from code bearing the copyright notice:
Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
This material may be freely distributed, provided this notice is retained.
This material is provided as is, with no warranty expressed or implied.
Use at your own risk.
endcopyright */
# define DEBUG_SMASH
# include "xr/GCPrivate.h"
# ifdef DIRTY_BITS
# include "sys/mman.h"
# endif
# define MAX_HEADER_AREAS 256
/*
* Boehm, February 22, 1991 3:12:53 pm PST
*/
# ifdef SEPARATE_HEADERS
/* Should be static, but not scanned. Must match decl in GCglobals.c */
extern struct hdr_area {
char * ha_start;
char * ha_end;
} GC_header_areas[];
# define header_areas GC_header_areas
int GC_num_ha = 0;
# define num_ha GC_num_ha
# ifdef DEBUG_SMASH
hdr * GC_last_allocated_hdr;
hdr * GC_previous_allocated_hdr;
void GC_print_ptr(p)
word * p;
{
XR_ConsoleMsg("0x%X -> 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X, 0x%X\n",
p, p[0], p[1], p[2], p[3], p[4], p[5], p[6]);
}
# endif
/* Return a previously unallocated hblk header. No guarantees are made */
/* about its contents. */
hdr * GC_alloc_hdr()
{
hdr * result;
if (GC_hdr_fl != HDR_NIL) {
result = GC_hdr_fl;
GC_hdr_fl = link(GC_hdr_fl);
# ifdef DEBUG_SMASH
GC_previous_allocated_hdr = GC_last_allocated_hdr;
GC_last_allocated_hdr = result;
if ((char *)GC_hdr_fl < GC_heapstart
|| (char *)GC_hdr_fl > GC_heaplim + 1000000) {
if (GC_hdr_fl == 0) {
XR_ConsoleMsg("Surprisingly short of hblk headers\n");
} else {
XR_ConsoleMsg("Smashed header free list: 0x%X\n",
GC_hdr_fl);
}
XR_ConsoleMsg("Last allocated header:\n");
GC_print_ptr(GC_last_allocated_hdr);
XR_ConsoleMsg("Previously allocated header:\n");
GC_print_ptr(GC_previous_allocated_hdr);
}
# endif
} else {
GC_abort("Out of memory for block headers\n");
}
return(result);
}
/* Release the block at h of size n * HBLKSIZE for use as heap block headers */
/* Must be called sufficiently frequently that we never run out. */
void GC_use_as_headers(h, n)
word * h;
long n;
{
register hdr * p;
register long lim;
if (num_ha + 1 >= MAX_HEADER_AREAS) {
/* Throw this one away, and hope for the best. */
GC_iprintf("Too many header areas; discarding one!\n");
return;
}
lim = ((long) h) + n * HBLKSIZE;
header_areas[num_ha].ha_start = (char *)h;
header_areas[num_ha].ha_end = (char *)lim;
num_ha++;
for (p = (hdr *)h; (long)(p+2) <= lim; p++) {
set_link(p, p + 1);
}
set_link(p, GC_hdr_fl);
GC_hdr_fl = (hdr *)h;
}
# ifdef DIRTY_BITS
/* Unprotect all pages in memory that include only headers. */
/* This interacts with GCVirtualDirty.c. It may safely */
/* be called at any time, PROVIDED we do not care about dirty */
/* bit information on the headers. Calling it may improve */
/* performance. Note however, that it only affects the */
/* current virtual processor. */
/* This makes sense only if virtual dirty bits are */
/* implemented with mprotect. */
void GC_unprotect_headers()
{
register int i;
register long base;
register long len;
register int ps = XR_GetPageSize();
for (i = 0; i < num_ha; i++) {
base = (((long)(header_areas[i].ha_start)) + ps-1) & ~(ps-1);
len = (((long)(header_areas[i].ha_end)) & ~(ps-1)) - base;
if (len > 0
&& mprotect(base, len, PROT_READ | PROT_WRITE | PROT_EXEC) < 0) {
GC_iprintf("GC_unprotect_headers failed on (0x%X,%d)\n",
base, len);
}
}
}
# endif DIRTY_BITS
/* Make sure that a header is available for heap block h */
void GC_get_header(h)
struct hblk * h;
{
long indx = h - (struct hblk *)GC_heapstart;
if (headers[indx] == HDR_NIL) {
headers[indx] = GC_alloc_hdr();
}
}
# ifdef UNDEFINED
/* Currently we allocate headers lazily, but we never free them. */
void GC_free_hdr(p)
hdr *p;
{
set_link(p, GC_hdr_fl);
GC_hdr_fl = p;
}
# endif UNDEFINED
# endif